package com.tengju.bff.interfaces.covercharge.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.idanchuang.component.redis.util.RedisUtil;
import com.tengju.bff.domain.shared.JsonUtil;
import com.tengju.bff.interfaces.covercharge.constant.*;
import com.tengju.bff.interfaces.covercharge.dto.BankInfo;
import com.tengju.bff.interfaces.covercharge.entity.dto.CycleAddInfo;
import com.tengju.bff.interfaces.covercharge.entity.dto.RegisteredInfo;
import com.tengju.bff.interfaces.covercharge.entity.dto.ServiceWithdarwCycleAddDto;
import com.tengju.bff.interfaces.covercharge.entity.po.*;
import com.tengju.bff.interfaces.covercharge.entity.vo.*;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceTaskMapper;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceWithdarwCycleAddMapper;
import com.tengju.bff.interfaces.covercharge.service.*;
import com.tengju.bff.interfaces.covercharge.util.DateTimeUtils;
import com.tengju.bff.interfaces.covercharge.util.alarmUtil.MsgSendUtil;
import com.tengju.payment.application.shard.ApplicationException;
import com.tengju.payment.application.shard.ApplicationExceptionCode;
import com.tengju.payment.application.transfer.TransferService;
import com.tengju.payment.domain.model.AccountType;
import com.tengju.payment.domain.model.TradeStatus;
import com.tengju.payment.domain.model.transfer.*;
import com.tengju.payment.domain.shard.Amount;
import com.tengju.payment.domain.shard.DoubleCalculator;
import com.tengju.settlement.domain.model.account.UserIdCode;
import com.tengju.settlement.domain.model.depository.AccountStatus;
import com.tengju.settlement.domain.model.depository.DepositoryAccount;
import com.tengju.settlement.domain.model.depository.DepositoryAccountRepository;
import com.tengju.settlement.domain.model.depository.DepositoryChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务费体现周期累计表 服务实现类
 * </p>
 *
 * @author zhaoyi
 * @since 2020-02-24
 */
@Slf4j
@Service
public class ServiceWithdarwCycleAddServiceImpl extends ServiceImpl<ServiceWithdarwCycleAddMapper, ServiceWithdarwCycleAdd> implements IServiceWithdarwCycleAddService {

    /**
     * 服务费提现金额对比状态:正常
     */
    private static final Integer SERVICE_WITHDRAW_CYCLE_ADD_CHECK_LOG_STATUS_NORMAL = 0;

    /**
     * 服务费提现金额对比状态:异常
     */
    private static final Integer SERVICE_WITHDRAW_CYCLE_ADD_CHECK_LOG_STATUS_ABNORMAL = 1;

    /**
     * 重试次数
     */
    private static final int RETRY_NUM = 0;

    /**
     * 周期数据校验每页参数
     */
    private static final int pageSize = 20000;

    @Value("${depository.account.whiteList}")
    private String DepAccountWhiteList;

    @Autowired
    @Lazy
    private IServiceLetaxWithdrawLogService serviceLetaxWithdrawLogService;

    @Autowired
    @Lazy
    private ServiceLetaxWithdrawLogServiceImpl serviceLetaxWithdrawLogServiceImpl;

    @Autowired
    private IServiceWithdrawCycleAddCheckLogService serviceWithdrawCycleAddCheckLogService;

    @Autowired
    private IServiceWithdarwCycleAddTransOrderService serviceWithdarwCycleAddTransOrderService;

    @Autowired
    private IServiceRabbitMqService rabbitMqService;

    @Autowired
    private TransferService transferService;

    @Autowired
    private IServiceLetaxRegisteredService serviceLetaxRegisteredService;

    @Autowired
    private ServiceTaskMapper taskMapper;

    @Autowired
    private DepositoryAccountRepository depositoryAccountRepository;

    @Value("${system.env}")
    String env;

    /**
     * 注册个体户,个人提现申请打款校验
     *
     * @param cycleAddId 周期id
     */
    @Override
    public PayMoneyResult onlinePayMoneyCheck(Integer cycleAddId) {
        if (cycleAddId == null) {
            return payMoneyResultData(false, "提现周期id为空");
        }
        //提示语
        String alertTitle = "序号为" + cycleAddId + "的周期记录";
        ServiceWithdarwCycleAdd cycleAdd = this.getById(cycleAddId);
        if (Objects.isNull(cycleAdd)) {
            return payMoneyResultData(false, alertTitle + "在周期表中找不到相对于记录！");
        }

        boolean hitWhiteList = false;
        if (!StringUtils.isEmpty(DepAccountWhiteList)) {
            List<UserIdCode> whiteIdCodeList = Arrays.stream(DepAccountWhiteList.split(","))
                    .map(Long::parseLong)
                    .map(UserIdCode::new)
                    .collect(Collectors.toList());
            hitWhiteList = whiteIdCodeList.contains(new UserIdCode(cycleAdd.getIdCode()));
        }

        //命中白名单 不允许线上打款
        if (hitWhiteList) {
            throw ApplicationException.error(ApplicationExceptionCode.WHITE_LIST_MEMBER_NOT_ALLOWED);
        } else {
            //存管开户校验
            DepositoryAccount depositoryAccount = depositoryAccountRepository
                    .getByIdCodeStatusNormal(new UserIdCode(cycleAdd.getIdCode()), DepositoryChannel.PING_AN);
            if (depositoryAccount == null || depositoryAccount.getStatus() != AccountStatus.NORMAL) {
                throw ApplicationException.error(ApplicationExceptionCode.DEP_ACCOUNT_NOT_OPEN);
            }
        }


        //金额必须大于0
        if (cycleAdd.getTotal().compareTo(BigDecimal.ZERO) <= 0) {
            return payMoneyResultData(false, alertTitle + "打款金额必须大于0");
        }

        //是否是乐税注册提现
        if (!serviceLetaxWithdrawLogService.isLeTaxUser(cycleAddId)) {
            return payMoneyResultData(false, alertTitle + "不是乐税注册个体户提现，不能打款！");
        }

        //幂等校验
        PayMoneyResult orderPayMoneyResult = cycleAddTransOrderCheck(cycleAddId, alertTitle, cycleAdd.getWithdrawStatus(), false);
        if (!orderPayMoneyResult.isPayResult()) {
            return orderPayMoneyResult;
        }
        //判断该周期有没有结束
        Date nowDate = new Date();
        if (cycleAdd.getEndAt().compareTo(nowDate) >= 0) {
            return payMoneyResultData(false, alertTitle + "没有结束，不能打款！");
        }
        //判断该周期数据有没有校验
        String startTime = DateTimeUtils.dateParseString(cycleAdd.getStartAt());
        String endTime = DateTimeUtils.dateParseString(cycleAdd.getEndAt());
        if (!serviceWithdrawCycleAddCheckLogService.getCheckLogInfo(startTime, endTime)) {
            return payMoneyResultData(false, alertTitle + "数据校验没有通过，请先去进行校验！");
        }
        //查看本周期记录是否全部审核通过
        QueryWrapper<ServiceLetaxWithdrawLog> withdrawLogQueryWrapper = new QueryWrapper<>();
        withdrawLogQueryWrapper.eq("cycle_add_id", cycleAdd.getId());
        withdrawLogQueryWrapper.in("status", List.of(LetaxWithdrawStatusEnum.APPLY.getCode(),LetaxWithdrawStatusEnum.PUTFAIL.getCode()));
        if (serviceLetaxWithdrawLogService.count(withdrawLogQueryWrapper) > 0) {
            return payMoneyResultData(false, alertTitle + "还有待审核或发放失败的提现记录");
        }
        return payMoneyResultData(true, "校验通过");
    }

    /**
     * 注册个体户,个人提现周期交易表校验
     *
     * @param cycleAddId     周期id
     * @param alertTitle     标题
     * @param withdrawStatus 周期状态
     * @param isMq           是否是Mq
     */
    private PayMoneyResult cycleAddTransOrderCheck(Integer cycleAddId, String alertTitle, Integer withdrawStatus, Boolean isMq) {
        //周期表状态判断
        if (ServiceWithdarwCycleAddEnum.HAVE_PAY.getCode().equals(withdrawStatus)) {
            return payMoneyResultData(false, alertTitle + "已经打款成功，请勿重复打款！");
        }

        //查找有没有打款成功的数据
        if (Objects.nonNull(serviceWithdarwCycleAddTransOrderService.getSuccessful(cycleAddId))) {
            return payMoneyResultData(false, alertTitle + "已经打款成功，请勿重复打款！");
        }

        //不是MQ，查找周期交易表有没有正在处理中或者未知的打款的数据
        if (!isMq && Objects.nonNull(serviceWithdarwCycleAddTransOrderService.getProcessOrUnKnow(cycleAddId, false))) {
            return payMoneyResultData(false, alertTitle + "正在打款中，请勿重复打款！");
        }

        return payMoneyResultData(true, "校验通过");
    }

    /**
     * 注册个体户,个人提现申请全量后置打款校验
     *
     * @param cycleAddId 周期id
     */
    @Override
    public PayMoneyResult onlineAllPayMoneyCheck(Integer cycleAddId) {
        //先校验每笔数据
        String alertTitle = "序号为" + cycleAddId + "的周期记录";
        if (cycleAddId == null) {
            return payMoneyResultData(false, "提现周期id为空");
        }
        ServiceWithdarwCycleAdd cycleAdd = this.getById(cycleAddId);
        if (Objects.isNull(cycleAdd)) {
            return payMoneyResultData(false, alertTitle + "在周期表中找不到相对于记录！");
        }

        boolean hitWhiteList = false;
        if (!StringUtils.isEmpty(DepAccountWhiteList)) {
            List<UserIdCode> whiteIdCodeList = Arrays.stream(DepAccountWhiteList.split(","))
                    .map(Long::parseLong)
                    .map(UserIdCode::new)
                    .collect(Collectors.toList());
            hitWhiteList = whiteIdCodeList.contains(new UserIdCode(cycleAdd.getIdCode()));
        }

        //命中白名单 不允许线上打款
        if (hitWhiteList) {
            throw ApplicationException.error(ApplicationExceptionCode.WHITE_LIST_MEMBER_NOT_ALLOWED);
        } else {
            //存管开户校验
            DepositoryAccount depositoryAccount = depositoryAccountRepository
                    .getByIdCodeStatusNormal(new UserIdCode(cycleAdd.getIdCode()), DepositoryChannel.PING_AN);
            if (depositoryAccount == null || depositoryAccount.getStatus() != AccountStatus.NORMAL) {
                throw ApplicationException.error(ApplicationExceptionCode.DEP_ACCOUNT_NOT_OPEN);
            }
        }

        //金额必须大于0
        if (cycleAdd.getTotal().compareTo(BigDecimal.ZERO) <= 0) {
            return payMoneyResultData(false, alertTitle + "打款金额必须大于0");
        }

        //是否是乐税注册提现
        if (!serviceLetaxWithdrawLogService.isLeTaxUser(cycleAddId)) {
            return payMoneyResultData(false, alertTitle + "不是乐税注册个体户提现，不能打款！");
        }

        //幂等校验
        PayMoneyResult orderPayMoneyResult = cycleAddTransOrderCheck(cycleAddId, alertTitle, cycleAdd.getWithdrawStatus(), false);
        if (!orderPayMoneyResult.isPayResult()) {
            return orderPayMoneyResult;
        }
        return payMoneyResultData(true, "校验通过");
    }

    /**
     * 注册个体户,个人提现申请全量打款前置校验
     *
     * @param startDateStr 开始时间
     * @param endDateStr   结束时间
     * @return payMoneyResult
     */
    @Override
    public PayMoneyResult onlineFullPayMoneyCheck(String startDateStr, String endDateStr) {
        Date nowDate = new Date();
        Date endDateChekc = DateUtil.parseDateTime(endDateStr);
        //判断该周期是不是已经完成了
        if (endDateChekc.compareTo(nowDate) >= 0) {
            return this.payMoneyResultData(false, "周期没有结束，不能打款！");
        }
        //判断该周期数据有没有校验
        if (!serviceWithdrawCycleAddCheckLogService.getCheckLogInfo(startDateStr, endDateStr)) {
            return this.payMoneyResultData(false, "周期数据校验没有通过，请先去进行校验！");
        }
        //判断该周期的提现记录是否已全部审批通过
        QueryWrapper<ServiceLetaxWithdrawLog> withdrawLogQueryWrapper = new QueryWrapper<>();
        withdrawLogQueryWrapper.ge("created_at", startDateStr);
        withdrawLogQueryWrapper.le("created_at", endDateStr);
        withdrawLogQueryWrapper.in("status", List.of(LetaxWithdrawStatusEnum.APPLY.getCode(),LetaxWithdrawStatusEnum.PUTFAIL.getCode()));

        if (serviceLetaxWithdrawLogService.count(withdrawLogQueryWrapper) > 0) {
            return this.payMoneyResultData(false, "周期还有提现记录没有审核通过或发放失败的记录，请确认！");
        }
        return this.payMoneyResultData(true, "校验通过");
    }

    /**
     * 注册个体户,个人提现申请批量打款
     *
     * @param cycleAddInfo 周期数据
     */
    @Override
    public PayMoneyResult dealOnlinePayMoney(CycleAddInfo cycleAddInfo) {
        //提示语
        String alertTitle = "序号为" + cycleAddInfo.getCycleAddId() + "的周期记录";
        if (cycleAddInfo.getCycleAddId() == null) {
            log.error("[服务费后台][个人收益打款申请记录][周期打款][提现周期id为空！]");
            //失败释放缓存
            delRedisKey(cycleAddInfo.getCycleAddId());
            return payMoneyResultData(false, alertTitle + "提现周期id为空！");
        }
        ServiceWithdarwCycleAdd cycleAddDb = this.getById(cycleAddInfo.getCycleAddId());
        if (Objects.isNull(cycleAddDb)) {
            log.error("[服务费后台][个人收益打款申请记录][周期打款][" + alertTitle + "在周期表中找不到相对于记录！]");
            //失败释放缓存
            delRedisKey(cycleAddInfo.getCycleAddId());
            return payMoneyResultData(false, alertTitle + "在周期表中找不到相对于记录！");
        }

        //周期幂等校验（防重复消费）
        PayMoneyResult orderPayMoneyResult = cycleAddTransOrderCheck(cycleAddInfo.getCycleAddId(), alertTitle, cycleAddDb.getWithdrawStatus(), true);
        if (!orderPayMoneyResult.isPayResult()) {
            //失败释放缓存
            delRedisKey(cycleAddInfo.getCycleAddId());
            return orderPayMoneyResult;
        }

        //周期结果
        ServiceWithdarwCycleAddDto cycleAdd = new ServiceWithdarwCycleAddDto();
        cycleAdd.setId(cycleAddDb.getId());
        cycleAdd.setIdCode(cycleAddDb.getIdCode());
        cycleAdd.setRatio(cycleAddDb.getRatio());
        cycleAdd.setTotal(cycleAddDb.getTotal());
        cycleAdd.setStartAt(cycleAddDb.getStartAt().toString());
        cycleAdd.setEndAt(cycleAddDb.getEndAt().toString());
        cycleAdd.setAccountId(cycleAddDb.getAccountId());

        //获取周期交易表记录
        ServiceWithdarwCycleAddTransOrder serviceWithdarwCycleAddTransOrder = serviceWithdarwCycleAddTransOrderService.getProcessOrUnKnow(cycleAddDb.getId(), false);
        if (Objects.isNull(serviceWithdarwCycleAddTransOrder)) {
            log.error("[服务费后台][个人收益打款申请记录][周期打款][" + alertTitle + "在周期交易表中找不到相对于记录！]");
            //失败释放缓存
            delRedisKey(cycleAddInfo.getCycleAddId());
            return payMoneyResultData(false, alertTitle + "在周期交易表中找不到相对于记录！");
        }

        log.info("[服务费后台][个人收益打款申请记录][周期打款][周期次数]" + serviceWithdarwCycleAddTransOrder.getNum());

        cycleAdd.setMerDate(serviceWithdarwCycleAddTransOrder.getCreatedTime().toString());
        cycleAdd.setAlertTitle(alertTitle);
        cycleAdd.setAddTransOrderId(serviceWithdarwCycleAddTransOrder.getId());
        cycleAdd.setType(cycleAddInfo.getType());
        cycleAdd.setBusinessNo(serviceWithdarwCycleAddTransOrder.getBusinessNo());
        cycleAdd.setNum(serviceWithdarwCycleAddTransOrder.getNum());

        return payMoneyDealData(cycleAdd);
    }


    /**
     * 生成交易单
     *
     * @param cycleAddId 周期id
     * @param approvers  打款人
     */
    @Override
    public void createCycleAddTransOrder(Integer cycleAddId, String approvers) {
        //当前时间
        Date nowDate = new Date();
        ServiceWithdarwCycleAddTransOrder serviceWithdarwCycleAddTransOrder = new ServiceWithdarwCycleAddTransOrder();
        //生成记录
        serviceWithdarwCycleAddTransOrder.setCycleAddId(cycleAddId);
        serviceWithdarwCycleAddTransOrder.setBusinessNo(String.valueOf(IdWorker.getId()));
        serviceWithdarwCycleAddTransOrder.setStatus(ServiceWithdarwCycleAddTransOrderEnum.DEALING.getCode());
        serviceWithdarwCycleAddTransOrder.setWithdrawer(approvers);
        serviceWithdarwCycleAddTransOrder.setCreatedTime(nowDate);
        serviceWithdarwCycleAddTransOrder.setUpdatedTime(nowDate);
        serviceWithdarwCycleAddTransOrderService.save(serviceWithdarwCycleAddTransOrder);
    }

    /**
     * 注册个体户,个人提现申请获取提现记录信息
     *
     * @param cycleAdd 周期数据
     * @return
     */
    private PersonalGiveVo getWithdrawLogInfo(ServiceWithdarwCycleAddDto cycleAdd, WithdrawLogRecordVo withdrawLogRecordVo) {
        //打款数据准备
        PersonalGiveVo personalGiveVo = new PersonalGiveVo();
        String registeredInfoStr = withdrawLogRecordVo.getRegisteredInfo();
        if (SignIdentityEnum.person.toString().equals(withdrawLogRecordVo.getAuthType())) {
            BankInfo bankInfo = JSON.parseObject(registeredInfoStr, BankInfo.class);
            personalGiveVo.setIdcardName(bankInfo.getIdcardName());
            personalGiveVo.setIdcardNo(bankInfo.getIdcardNo());
            personalGiveVo.setBankName(bankInfo.getBankName());
            personalGiveVo.setBankNo(bankInfo.getBankNo());
            personalGiveVo.setAuthType("个人");
        } else if (SignIdentityEnum.regist_soho.toString().equals(withdrawLogRecordVo.getAuthType())) {
            List<RegisteredInfo> registeredInfoList = JSON.parseArray(registeredInfoStr, RegisteredInfo.class);
            if (CollectionUtil.isNotEmpty(registeredInfoList)) {
                RegisteredInfo registeredInfo = registeredInfoList.get(0);
                personalGiveVo.setIdcardName(registeredInfo.getIdcardName());
                personalGiveVo.setIdcardNo(registeredInfo.getIdcardNo());
                personalGiveVo.setBankName(registeredInfo.getBankName());
                personalGiveVo.setBankNo(registeredInfo.getBankNo());
                personalGiveVo.setMerchantName(registeredInfo.getMerchantName());
                personalGiveVo.setMerchantTaxNumber(registeredInfo.getMerchantTaxNumber());
            }
            personalGiveVo.setAuthType("注册个体户");
        }

        //已发放金额
        BigDecimal putMoney = serviceLetaxWithdrawLogService.sumMoney(cycleAdd.getId(), LetaxWithdrawStatusEnum.PUT.getCode());
        //待发放金额
        BigDecimal outMoney = cycleAdd.getTotal().subtract(putMoney);
        BigDecimal fee = cycleAdd.getTotal().multiply(cycleAdd.getRatio());
        outMoney = new BigDecimal(String.valueOf(outMoney.subtract(fee))).setScale(2, BigDecimal.ROUND_DOWN);//截取小数点后两位
        personalGiveVo.setPassMoney(cycleAdd.getTotal());
        personalGiveVo.setFee(fee);
        personalGiveVo.setMoney(outMoney);
        personalGiveVo.setPlatformCode(withdrawLogRecordVo.getPlatformCode());
        personalGiveVo.setAccountId(cycleAdd.getAccountId());
        personalGiveVo.setCycleAddId(cycleAdd.getId());
        personalGiveVo.setIdCode(cycleAdd.getIdCode());
        personalGiveVo.setAddTransOrderId(cycleAdd.getAddTransOrderId());
        personalGiveVo.setAddTransOrderNum(cycleAdd.getNum());
        personalGiveVo.setWithdrawer(cycleAdd.getWithdrawer());
        return personalGiveVo;
    }

    /**
     * 注册个体户,个人提现申请批量代发
     *
     * @param cycleAdd 周期数据
     * @return
     */
    private DealSinglePayResult dealSinglePay(ServiceWithdarwCycleAddDto cycleAdd, PersonalGiveVo personalGiveVo) {
        DealSinglePayResult dealSinglePayResult = new DealSinglePayResult();

        //乐税注销状态查找和更新
        log.info("[服务费后台][个人收益打款申请记录][周期打款][乐税注销状态查找和更新]idCode{},authType{}", cycleAdd.getIdCode(), personalGiveVo.getAuthType());
        if (SignIdentityEnum.regist_soho.getDesc().equals(personalGiveVo.getAuthType())) {
            PayMoneyResult payMoneyResult = updateWithdrawLogLetaxStatus(personalGiveVo.getPlatformCode(), personalGiveVo.getMerchantTaxNumber(), cycleAdd);
            if (!payMoneyResult.isPayResult()) {
                dealSinglePayResult.setPayResult(Boolean.FALSE);
                dealSinglePayResult.setNum(cycleAdd.getNum() + 1);
                dealSinglePayResult.setErrorMsg(payMoneyResult.getErrorMsg());
                return dealSinglePayResult;
            }
        }

        DepositoryAccount depositoryAccount =
                depositoryAccountRepository.getByIdCodeStatusNormal(new UserIdCode(cycleAdd.getIdCode()), DepositoryChannel.PING_AN);

        UnionTransferRequest transferRequest = new UnionTransferRequest(
                new BusinessNo(cycleAdd.getBusinessNo()),
                new Amount(DoubleCalculator.multiply(personalGiveVo.getMoney().doubleValue(), 100).intValue()),
                personalGiveVo.getIdcardName(),
                personalGiveVo.getBankNo(),
                AccountType.PERSON,
                "",
                "",
                CertificationTypeEnum.NO_CERTIFICATION,
                depositoryAccount.getDepositoryId()
        );

//        if ("dev".equals(env) || "test".equals(env)) {
//            //测试需要
//            transferRequest = new UnionTransferRequest(
//                    new BusinessNo(cycleAdd.getBusinessNo()),
//                    new Amount(DoubleCalculator.multiply(personalGiveVo.getMoney().doubleValue(), 100).intValue()),
//                    "李婉婷",
//                    "6225887839266918",
//                    AccountType.PERSON,
//                    "",
//                    "",
//                    CertificationTypeEnum.NO_CERTIFICATION
//            );
//        }

        log.info("[服务费后台][个人收益打款代发][服务开始请求],transferRequest:{}", transferRequest);

        UnionTransferResponse transferResponse = transferService.unionStoreTransfer(transferRequest);

        log.info("[服务费后台][个人收益打款代发][服务返回结果],transferResponse:{}", transferResponse);

        Integer num = cycleAdd.getNum();
        //默认未知
        Integer status = ServiceWithdarwCycleAddTransOrderEnum.UNKNOWN.getCode();
//        String returnMsg=transferResponse.getMsg();
//        if(transferResponse.getData()!=null){
//            String message="";
//            String channelMessage="";
//            if(transferResponse.getData().getMessage()!=null){
//                message=transferResponse.getData().getMessage();
//            }
//            if(transferResponse.getData().getChannelMessage()!=null){
//                channelMessage=transferResponse.getData().getChannelMessage();
//            }
//            returnMsg=message+channelMessage;
//        }
        String returnMsg = transferResponse.getMsg();
        //是否需要修改提现记录状态,默认不需要
        Boolean isUpdate = false;
        dealSinglePayResult.setPayResult(false);

        //服务调用失败，未知
        if (!transferResponse.isSuccess()) {
            num++;
            serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), num, status, returnMsg);
            dealSinglePayResult.setNum(num);
            dealSinglePayResult.setErrorMsg(returnMsg);
            log.error("[服务费后台][个人收益打款申请记录][周期脚本打款][调用代发服务失败],businessNo:{},returnMsg：{}", cycleAdd.getBusinessNo(), returnMsg);
            return dealSinglePayResult;
        }

        log.info("[服务费后台][个人收益打款代发][服务返回结果code],code:{}", transferResponse);

        //打款成功
        if (transferResponse.isSuccess() && TradeStatus.SUCCESS == transferResponse.getTradeStatus()) {
            personalGiveVo.setIsSuccess(true);
            status = ServiceWithdarwCycleAddTransOrderEnum.SUCCESSFUL.getCode();
            personalGiveVo.setChannel(transferResponse.getChannelName());
            returnMsg = "打款成功";
            isUpdate = true;
            dealSinglePayResult.setPayResult(true);
        }

        //打款失败
        if (transferResponse.isSuccess() && TradeStatus.FAIL == transferResponse.getTradeStatus()) {
            personalGiveVo.setIsSuccess(false);
            personalGiveVo.setChannel(transferResponse.getChannelName());
            num++;
            status = ServiceWithdarwCycleAddTransOrderEnum.FAILURE.getCode();
            //真正的打款失败
            //if(FundOutFeignClientCodeEnum.FAILURE.getCode().equals(transferResponse.getData().getCode())){
            isUpdate = true;
            //}else{
            //释放缓存
            delRedisKey(cycleAdd.getId());
            //}
        }


        //处理中
        if (transferResponse.isSuccess() && (TradeStatus.PROCESS == transferResponse.getTradeStatus() || TradeStatus.CREATED == transferResponse.getTradeStatus())) {
            num++;
            status = ServiceWithdarwCycleAddTransOrderEnum.DEALING.getCode();
        }

        //未知
//        if(FundOutFeignClientStatusEnum.UN_KNOW.getCode().equals(transferResponse.getData().getStatus())){
//            num++;
//        }

        //更新交易
        serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), num, status, returnMsg);
        //只有打款成功和失败才需要去进行周期表等一系列更新操作
        if (isUpdate) {
            //释放缓存
            delRedisKey(cycleAdd.getId());
            personalGiveVo.setReturnMsg(returnMsg);
            num = serviceLetaxWithdrawLogServiceImpl.dealPayReturnData(personalGiveVo);
        }
        dealSinglePayResult.setNum(num);
        dealSinglePayResult.setErrorMsg(returnMsg);
        return dealSinglePayResult;
    }

    /**
     * 注册个体户,个人提现申请批量查询打款
     *
     * @param cycleAdd 周期数据
     * @return
     */
    public DealSinglePayResult dealSinglePayQuery(ServiceWithdarwCycleAddDto cycleAdd, PersonalGiveVo personalGiveVo) {
//        Transfer transferOrderQueryRequest=new TransferOrderQueryRequest();
//        transferOrderQueryRequest.setBusinessNo(cycleAdd.getBusinessNo());
//        transferOrderQueryRequest.setMerDate(cycleAdd.getMerDate());
//        transferOrderQueryRequest.setApplicationBusiness(ApplicationBusinessEnum.getBusinessDesc(personalGiveVo.getPlatformCode()).getDesc());
//        transferOrderQueryRequest.setCertificationType(CertificationTypeEnum.NO_CERTIFICATION.getCode());
        log.info("[服务费后台][个人收益打款代发查询][服务开始请求],BusinessNo:{}", cycleAdd.getBusinessNo());

        Transfer transferOrderQueryResponse = transferService.findTransfer(new BusinessNo(cycleAdd.getBusinessNo()));

        log.info("[服务费后台][个人收益打款代发查询][服务返回结果],transferOrderQueryResponse:{}", JsonUtil.toJSONString(transferOrderQueryResponse));

        DealSinglePayResult dealSinglePayResult = new DealSinglePayResult();
        Integer num = cycleAdd.getNum();

        log.info("[服务费后台][个人收益打款代发查询][失败次数],num:{}", num);

        //默认未知
        Integer status = ServiceWithdarwCycleAddTransOrderEnum.UNKNOWN.getCode();
        String returnMsg = "";
//        if(transferOrderQueryResponse.getData()!=null){
//            String message="";
//            String channelMessage="";
//            if(transferOrderQueryResponse.getData().getMessage()!=null){
//                message=transferOrderQueryResponse.getData().getMessage();
//            }
//            if(transferOrderQueryResponse.getData().getChannelMessage()!=null){
//                channelMessage=transferOrderQueryResponse.getData().getChannelMessage();
//            }
//            returnMsg=message+channelMessage;
//        }
        Boolean isUpdate = false;//是否需要修改提现记录状态,默认不需要
        dealSinglePayResult.setPayResult(false);

        //服务调用失败，未知
        if (transferOrderQueryResponse == null) {
            num++;
            serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), num, status, "查询服务调用出错");
            dealSinglePayResult.setNum(num);
            dealSinglePayResult.setErrorMsg("查询服务调用出错");
            log.error("[服务费后台][个人收益打款申请记录][周期脚本打款][调用代发查询服务失败],businessNo:{},returnMsg：{}", cycleAdd.getBusinessNo(), "查询服务调用出错");
            return dealSinglePayResult;
        }

        //log.info("[服务费后台][个人收益打款代发查询][返回code],code:{}", transferOrderQueryResponse.getData().getCode());

        //针对订单不存在特殊情况处理就直接调用代发
//        if(FundOutFeignClientCodeEnum.ORDER_ERROR.getCode().equals(transferOrderQueryResponse.getData().getCode())){
//            DealSinglePayResult dealSinglePay=dealSinglePay(cycleAdd,personalGiveVo);
//            dealSinglePayResult.setPayResult(dealSinglePay.isPayResult());
//            dealSinglePayResult.setErrorMsg(dealSinglePay.getErrorMsg());
//            dealSinglePayResult.setNum(dealSinglePay.getNum());
//            return dealSinglePayResult;
//        }

        //打款成功
        if (TradeStatus.SUCCESS == transferOrderQueryResponse.getTradeStatus()) {
            personalGiveVo.setIsSuccess(true);
            status = ServiceWithdarwCycleAddTransOrderEnum.SUCCESSFUL.getCode();
            personalGiveVo.setChannel(transferOrderQueryResponse.getChannelType().getDesc());
            returnMsg = "打款成功";
            isUpdate = true;
            dealSinglePayResult.setPayResult(true);
        }

        //打款失败
        if (TradeStatus.FAIL == transferOrderQueryResponse.getTradeStatus()) {
            personalGiveVo.setIsSuccess(false);
            personalGiveVo.setChannel(transferOrderQueryResponse.getChannelType().getDesc());
            num++;
            status = ServiceWithdarwCycleAddTransOrderEnum.FAILURE.getCode();
            //真正的打款失败
            //if(FundOutFeignClientCodeEnum.FAILURE.getCode().equals(transferOrderQueryResponse.getData().getCode())){
            isUpdate = true;
            //}else{
            //释放缓存
            delRedisKey(cycleAdd.getId());
            //}
        }

        //处理中
        if (TradeStatus.PROCESS == transferOrderQueryResponse.getTradeStatus() || TradeStatus.CREATED == transferOrderQueryResponse.getTradeStatus()) {
            num++;
            status = ServiceWithdarwCycleAddTransOrderEnum.DEALING.getCode();
        }

        //未知
//        if(FundOutFeignClientStatusEnum.UN_KNOW.getCode().equals(transferOrderQueryResponse.getData().getStatus())){
//            num++;
//        }

        //更新交易
        log.info("[服务费后台][个人收益打款代发查询][失败次数更新],num:{}", num);
        serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), num, status, returnMsg);
        //打款成功和失败就要进行周期表，冻结明细，提现明细等更新操作
        if (isUpdate) {
            //释放缓存
            delRedisKey(cycleAdd.getId());
            personalGiveVo.setReturnMsg(returnMsg);
            num = serviceLetaxWithdrawLogServiceImpl.dealPayReturnData(personalGiveVo);
        }
        dealSinglePayResult.setNum(num);
        dealSinglePayResult.setErrorMsg(returnMsg);
        return dealSinglePayResult;
    }

    /**
     * 注册个体户,个人提现申请批量打款处理
     *
     * @param cycleAdd 周期数据
     * @return
     */
    public PayMoneyResult payMoneyDealData(ServiceWithdarwCycleAddDto cycleAdd) {
        WithdrawLogRecordVo withdrawLogRecordVo = serviceLetaxWithdrawLogService.queryLogByCycleAddId(cycleAdd.getId());
        if (withdrawLogRecordVo == null) {
            log.error("[服务费后台][个人收益打款申请记录][周期打款][" + cycleAdd.getAlertTitle() + "获取提现记录为空！]");
            //失败释放缓存
            delRedisKey(cycleAdd.getId());
            return payMoneyResultData(false, cycleAdd.getAlertTitle() + "获取提现记录为空！");
        }

        //乐税是否是注销状态
        if (LetaxWithdrawMerchantStatusEnum.YES.getCode().equals(withdrawLogRecordVo.getLetaxStatus())) {
            log.error("[服务费后台][个人收益打款申请记录][周期打款][" + cycleAdd.getAlertTitle() + "乐税商户为注销状态！]");
            serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), cycleAdd.getNum() + 1, ServiceWithdarwCycleAddTransOrderEnum.FAILURE.getCode(), "乐税商户为注销状态");
            //失败释放缓存
            delRedisKey(cycleAdd.getId());
            return payMoneyResultData(false, cycleAdd.getAlertTitle() + "乐税商户为注销状态！");
        }

        //打款数据准备
        PersonalGiveVo personalGiveVo = getWithdrawLogInfo(cycleAdd, withdrawLogRecordVo);

        //打款金额校验
        if (personalGiveVo.getMoney().compareTo(BigDecimal.ZERO) <= 0) {
            serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), cycleAdd.getNum() + 1, ServiceWithdarwCycleAddTransOrderEnum.FAILURE.getCode(), "打款金额必须要大于0");
            //失败释放缓存
            delRedisKey(cycleAdd.getId());
            return payMoneyResultData(false, cycleAdd.getAlertTitle() + "打款金额必须要大于0");
        }

        //更新处理的记录
        Integer dealCount = 0;
        if (OnlinePayMoneyTypeEnum.PAY.getCode().equals(cycleAdd.getType())) {
            //调用代发
            try {
                DealSinglePayResult dealSinglePayResult = dealSinglePay(cycleAdd, personalGiveVo);
                dealCount = dealSinglePayResult.getNum();
            } catch (Exception e) {
                log.error("[服务费后台][个人收益打款申请记录][周期打款][调用代发服务失败]", e);
                MsgSendUtil.sendLarkMsg("乐税个人转账记录发起失败,周期记录id：{}, 周期交易单号：{}"
                        , cycleAdd.getId()
                        , cycleAdd.getBusinessNo()
                );
                serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), cycleAdd.getNum() + 1, ServiceWithdarwCycleAddTransOrderEnum.UNKNOWN.getCode(), e.getMessage());
                return payMoneyResultData(false, cycleAdd.getAlertTitle() + "调用代发或者更新周期数据失败");
            }
        } else {
            //调用查询
            try {
                DealSinglePayResult dealSinglePayResult = dealSinglePayQuery(cycleAdd, personalGiveVo);
                dealCount = dealSinglePayResult.getNum();
                //等于重试最大次数，钉钉警告
                if (!dealSinglePayResult.isPayResult() && dealCount.compareTo(OnlinePayMoneyErrorNum.SERVICE_WITHDARE_CYCLE_ADD_TRANS) >= 0) {
                    MsgSendUtil.sendLarkMsg("[服务费后台][个人收益打款申请记录][周期脚本打款][调用代发查询服务失败次数超过上限]周期记录id：{}, 周期交易单号：{},错误信息：{}"
                            , cycleAdd.getId()
                            , cycleAdd.getBusinessNo()
                            , dealSinglePayResult.getErrorMsg()
                    );
                }
            } catch (Exception e) {
                log.error("[服务费后台][个人收益打款申请记录][周期脚本打款][调用代发查询服务失败]", e);
                Integer orderNum = cycleAdd.getNum() + 1;
                //等于重试最大次数，钉钉警告
                if (orderNum.equals(OnlinePayMoneyErrorNum.SERVICE_WITHDARE_CYCLE_ADD_TRANS)) {
                    MsgSendUtil.sendLarkMsg("[服务费后台][个人收益打款申请记录][周期脚本打款][调用代发查询服务失败次数超过上限]周期记录id：{}, 周期交易单号：{},错误信息：{}"
                            , cycleAdd.getId()
                            , cycleAdd.getBusinessNo()
                            , e.getMessage()
                    );
                }
                serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), orderNum, ServiceWithdarwCycleAddTransOrderEnum.UNKNOWN.getCode(), e.getMessage());
                return payMoneyResultData(false, cycleAdd.getAlertTitle() + "调用代发或者更新周期数据失败");
            }
        }
        log.info("[服务费后台][个人收益打款申请记录][周期打款][更新打款状态结束]，dealCount，{}", dealCount);
        return payMoneyResultData(true, "成功");
    }

    /**
     * 注册个体户,个人提现申请批量打款返回结果
     *
     * @param payResult 返回结果
     * @param msg       错误信息
     */
    private PayMoneyResult payMoneyResultData(Boolean payResult, String msg) {
        PayMoneyResult payMoneyResult = new PayMoneyResult();
        payMoneyResult.setPayResult(payResult);
        payMoneyResult.setErrorMsg(msg);
        return payMoneyResult;
    }

    @Override
    public CycleAddCheckTaskResult cycleAddCheckCreateTask(int allSize, String taskSey, String approvers) {
        ServiceTask task = new ServiceTask();
        task.setTaskNo(String.valueOf(IdWorker.getId())).setTaskKey(taskSey)
                .setBizType(TaskBizType.TYPE_1.getType()).
                setTaskSize(allSize).setTaskStatus(1).setTaskApplicant(approvers)
                .setCreateTime(LocalDateTime.now()).setUpdateTime(LocalDateTime.now());
        int num = taskMapper.insert(task);
        CycleAddCheckTaskResult taskResult = new CycleAddCheckTaskResult();
        if (num > 0) {
            taskResult.setTaskResult(true);
            taskResult.setTaskNo(task.getTaskNo());
            taskResult.setTaskKey(task.getTaskKey());
            return taskResult;
        }
        taskResult.setTaskResult(false);
        taskResult.setErrorMsg("创建任务失败，请稍后重试");
        return taskResult;
    }

    /**
     * 获取总数
     *
     * @param serviceWithdarwCycleAddQueryVO serviceWithdarwCycleAddQueryVO
     * @return vo
     */
    @Override
    public Integer sumTotal(ServiceWithdarwCycleAddQueryVO serviceWithdarwCycleAddQueryVO) {
        QueryWrapper<ServiceWithdarwCycleAdd> serviceWithdarwCycleAddQueryWrapper = new QueryWrapper<>();
        serviceWithdarwCycleAddQueryWrapper.eq("start_at", serviceWithdarwCycleAddQueryVO.getStartDateStr());
        serviceWithdarwCycleAddQueryWrapper.eq(serviceWithdarwCycleAddQueryVO.getIdCode() != null, "id_code", serviceWithdarwCycleAddQueryVO.getIdCode());
        return this.baseMapper.selectCount(serviceWithdarwCycleAddQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceWithdarwCycleAddVO getAllTotal(ServiceWithdarwCycleAddQueryVO serviceWithdarwCycleAddQueryVO) {
        QueryWrapper<ServiceWithdarwCycleAdd> serviceWithdarwCycleAddQueryWrapper = new QueryWrapper<>();
        serviceWithdarwCycleAddQueryWrapper.eq("start_at", serviceWithdarwCycleAddQueryVO.getStartDateStr());
        serviceWithdarwCycleAddQueryWrapper.eq(serviceWithdarwCycleAddQueryVO.getIdCode() != null, "id_code", serviceWithdarwCycleAddQueryVO.getIdCode());
        serviceWithdarwCycleAddQueryWrapper.select("sum(total) as total");
        ServiceWithdarwCycleAdd serviceWithdarwCycleAdd = this.baseMapper.selectOne(serviceWithdarwCycleAddQueryWrapper);

        QueryWrapper<ServiceLetaxWithdrawLog> serviceLetaxWithdrawLogQueryWrapper = new QueryWrapper<>();
        serviceLetaxWithdrawLogQueryWrapper.between("created_at", serviceWithdarwCycleAddQueryVO.getStartDateStr(), serviceWithdarwCycleAddQueryVO.getEndDateStr());
        serviceLetaxWithdrawLogQueryWrapper.notIn("status", 3, 6);
        serviceLetaxWithdrawLogQueryWrapper.eq(serviceWithdarwCycleAddQueryVO.getIdCode() != null, "id_code", serviceWithdarwCycleAddQueryVO.getIdCode());
        serviceLetaxWithdrawLogQueryWrapper.select("sum(money) as money");
        ServiceLetaxWithdrawLog serviceLetaxWithdrawLog = serviceLetaxWithdrawLogService.getBaseMapper().selectOne(serviceLetaxWithdrawLogQueryWrapper);

        ServiceWithdarwCycleAddVO serviceWithdarwCycleAddVO = new ServiceWithdarwCycleAddVO();
        serviceWithdarwCycleAddVO.setAllTotal(serviceWithdarwCycleAdd != null ? serviceWithdarwCycleAdd.getTotal() : BigDecimal.ZERO);
        serviceWithdarwCycleAddVO.setDetailAllTotal(serviceLetaxWithdrawLog != null ? serviceLetaxWithdrawLog.getMoney() : BigDecimal.ZERO);
        BigDecimal shortFall = serviceWithdarwCycleAddVO.getAllTotal().subtract(serviceWithdarwCycleAddVO.getDetailAllTotal());
        serviceWithdarwCycleAddVO.setShortfall(shortFall);

        //插入比对结果记录
        LocalDateTime nowDateTime = LocalDateTime.now();
        ServiceWithdrawCycleAddCheckLog serviceWithdrawCycleAddCheckLog = new ServiceWithdrawCycleAddCheckLog()
                .setStartAt(serviceWithdarwCycleAddQueryVO.getStartDateStr())
                .setEndAt(serviceWithdarwCycleAddQueryVO.getEndDateStr())
                .setCreateTime(nowDateTime)
                .setUpdateTime(nowDateTime)
                .setStatus(SERVICE_WITHDRAW_CYCLE_ADD_CHECK_LOG_STATUS_NORMAL);
        //比较周期提现总金额和周期提现明细累计总金额是否一致
        boolean checkCycleAddFlag = serviceWithdarwCycleAddVO.getAllTotal().compareTo(serviceWithdarwCycleAddVO.getDetailAllTotal()) == 0;
        //比较周期提现每笔金额和对应提现明细金额累计是否一致
        boolean checkCycleAddDetailFlag = this.checkCycleAddDetail(serviceWithdarwCycleAddQueryVO.getStartDateStr(), serviceWithdarwCycleAddQueryVO.getIdCode());
        //定义task任务
        int taskStatus = 2;
        Integer successSize = serviceWithdarwCycleAddQueryVO.getNum();
        Integer failSize = 0;
        if (!checkCycleAddFlag || !checkCycleAddDetailFlag) {
            serviceWithdrawCycleAddCheckLog.setStatus(SERVICE_WITHDRAW_CYCLE_ADD_CHECK_LOG_STATUS_ABNORMAL);
            taskStatus = 3;
            failSize = serviceWithdarwCycleAddQueryVO.getNum();
            successSize = 0;
        }

        log.info("[服务费后台][周期校验结果]，checkCycleAddFlag={}，checkCycleAddDetailFlag={}", checkCycleAddFlag, checkCycleAddDetailFlag);

        //周期总数对不上
        if (!checkCycleAddFlag) {
            MsgSendUtil.sendLarkMsg("服务费周期提现总金额和明细总金额异常, 周期：{}, 提现总额：{}, 提现明细总额：{}, 差额：{}"
                    , serviceWithdarwCycleAddQueryVO.getCycleDate(), serviceWithdarwCycleAddVO.getAllTotal()
                    , serviceWithdarwCycleAddVO.getDetailAllTotal(), shortFall);
        }

        //周期总金额对上了，明细对不上
        if (checkCycleAddFlag && !checkCycleAddDetailFlag) {
            MsgSendUtil.sendLarkMsg("服务费周期提现单笔金额和明细金额异常, 周期：{}, 提现总额：{}, 提现明细总额：{}"
                    , serviceWithdarwCycleAddQueryVO.getCycleDate(), serviceWithdarwCycleAddVO.getAllTotal()
                    , serviceWithdarwCycleAddVO.getDetailAllTotal());
        }

        serviceWithdrawCycleAddCheckLogService.save(serviceWithdrawCycleAddCheckLog);

        //更新任务
        updateCycleCheckTask(serviceWithdarwCycleAddQueryVO.getTaskNo(), taskStatus, successSize, failSize);

        return serviceWithdarwCycleAddVO;
    }

    /**
     * 更新任务
     *
     * @param taskNo      任务标识
     * @param status      状态
     * @param successSize 成功数
     * @param failSize    失败数
     * @return null
     **/
    @Override
    public void updateCycleCheckTask(String taskNo, Integer status, Integer successSize, Integer failSize) {
        //更新任务
        ServiceTask updateTask = new ServiceTask();
        updateTask.setTaskNo(taskNo);
        ServiceTask task = new ServiceTask();
        task.setTaskStatus(status).setUpdateTime(LocalDateTime.now()).setSuccessSize(successSize).setFailSize(failSize);
        taskMapper.update(task, new UpdateWrapper<>(updateTask));
    }

    @Override
    public IPage<ServiceWithdarwCycleAddVO> checkErrorPage(ServiceWithdarwCycleAddQueryVO serviceWithdarwCycleAddQueryVO) {
        Page page = new Page(serviceWithdarwCycleAddQueryVO.getPageNo(), serviceWithdarwCycleAddQueryVO.getLimit());
        return this.baseMapper.checkErrorPage(page, serviceWithdarwCycleAddQueryVO);
    }

    /**
     * 校验周期表提现金额和周期提现明细累计金额
     *
     * @param startAt 周期开始时间
     * @param idCode  代码id(查询参数，可以不传)
     * @return flag
     */
    private boolean checkCycleAddDetail(String startAt, Integer idCode) {
        boolean flag = true;
        QueryWrapper<ServiceWithdarwCycleAdd> serviceWithdrawCycleAddQueryWrapper = new QueryWrapper<>();
        serviceWithdrawCycleAddQueryWrapper.eq("start_at", startAt);
        serviceWithdrawCycleAddQueryWrapper.eq(idCode != null, "id_code", idCode);

        int count = this.baseMapper.selectCount(serviceWithdrawCycleAddQueryWrapper);
        if (count == 0) {
            return true;
        }
        //循环遍历每页
        for (int i = 1; i <= getPage(count); i++) {
            Page<ServiceWithdarwCycleAdd> pageResult = this.baseMapper.selectPage(new Page<>(i, pageSize), serviceWithdrawCycleAddQueryWrapper);
            List<ServiceWithdarwCycleAdd> list = pageResult.getRecords();
            if (CollectionUtils.isEmpty(list)) {
                return true;
            }
            for (ServiceWithdarwCycleAdd serviceWithdrawCycleAdd : list) {
                QueryWrapper<ServiceLetaxWithdrawLog> serviceLetaxWithdrawLogQueryWrapper = new QueryWrapper<>();
                serviceLetaxWithdrawLogQueryWrapper.eq("cycle_add_id", serviceWithdrawCycleAdd.getId());
                serviceLetaxWithdrawLogQueryWrapper.notIn("status", 3, 6);
                serviceLetaxWithdrawLogQueryWrapper.eq(idCode != null, "id_code", idCode);
                serviceLetaxWithdrawLogQueryWrapper.select("IFNULL( sum( money ), 0 ) as money");
                ServiceLetaxWithdrawLog serviceLetaxWithdrawLog = serviceLetaxWithdrawLogService.getOne(serviceLetaxWithdrawLogQueryWrapper);

                //如果周期金额大于0，且提现记录没有信息
                if (serviceWithdrawCycleAdd.getTotal().compareTo(BigDecimal.ZERO) > 0 && Objects.isNull(serviceLetaxWithdrawLog)) {
                    flag = false;
                    log.warn("[ServiceWithdarwCycleAddServiceImpl]-[checkCycleAddDetail]-[errorMSg:{}]", "周期提现明细记录为空" + serviceWithdrawCycleAdd.getId());
                    break;
                }

                if (serviceWithdrawCycleAdd.getTotal().compareTo(serviceLetaxWithdrawLog.getMoney()) != 0) {
                    flag = false;
                    log.warn("[ServiceWithdarwCycleAddServiceImpl]-[checkCycleAddDetail]-[errorMSg:{}]", "周期提现金额跟周期提现明细累计金额不一致" + serviceWithdrawCycleAdd.getId());
                    break;
                }
            }
        }

        return flag;
    }

    /**
     * 周期打款MQ处理
     * @param cycleAddInfo 周期数据
     * @return
     * */
//    @Override
//    public void sendOnlinePayMoneyMessage(CycleAddInfo cycleAddInfo) {
//        String topic = MqMessageConstants.SERVICE_CYCLE_ONLINE_PAY_MONEY_NOTIFY;
//        String routeKey = MqMessageConstants.SERVICE_CYCLE_ONLINE_PAY_MONEY_CALLBACK;
//        RabbitMqMessage mqMessage = new RabbitMqMessage();
//        mqMessage.setMessageId(cycleAddInfo.getBizId());
//        mqMessage.setTopic(topic);
//        mqMessage.setRouteKey(routeKey);
//        mqMessage.setNum(0);
//        mqMessage.setCycleAddInfo(cycleAddInfo);
//        mqMessage.setCreateTime(new Date());
//        rabbitMqService.sendMessage(topic, routeKey, mqMessage, null);
//    }

    /**
     * 周期打款，MQ消费处理
     * @param deliveryTag
     * @param channel
     * @param message
     * @return
     * */
//    @Override
//    public void dealOnlinePayMoneyMessage(Long deliveryTag, Channel channel, RabbitMqMessage message) throws Exception{
//        //含幂等校验
//        try {
//            CycleAddInfo cycleAddInfo=message.getCycleAddInfo();
//            dealOnlinePayMoney(cycleAddInfo);
//        } catch (Exception e) {
//            log.error("[服务费后台][个人收益打款申请记录][MQ打款失败,有异常抛出]", e);
//        }
//        //取消消费
//        channel.basicAck(deliveryTag, true);
//    }

    /**
     * 获取周期列表
     *
     * @param startDateStr 周期开始时间
     * @param endDateStr   周期结束时间
     * @return list
     */
    @Override
    public List<ServiceWithdarwCycleAdd> queryCycleAddList(String startDateStr, String endDateStr) {
        QueryWrapper<ServiceWithdarwCycleAdd> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("start_at", startDateStr);
        queryWrapper.eq("end_at", endDateStr);
        return this.list(queryWrapper);
    }

    /**
     * 获取周期提交参数
     *
     * @param cycleAddId 周期id
     * @param approvers  打款人
     * @return CycleAddInfo
     */
    @Override
    public CycleAddInfo getCycleAddInfo(Integer cycleAddId, String approvers) {
        CycleAddInfo cycleAddInfo = new CycleAddInfo();
        cycleAddInfo.setApprovers(approvers);
        cycleAddInfo.setCycleAddId(cycleAddId);
        cycleAddInfo.setBizId(String.valueOf(IdWorker.getId()));
        cycleAddInfo.setType(OnlinePayMoneyTypeEnum.PAY.getCode());
        return cycleAddInfo;
    }

    /**
     * 释放缓存
     *
     * @param cycleAddId 周期id
     */
    @Override
    public void delRedisKey(Integer cycleAddId) {
        String lockKey = BizConstants.SERVICE_WITHDRAW_CYCLE_ADD_ONLINE_PAY_MONEY + cycleAddId;
        Integer cycleId = RedisUtil.getInstance().getObj(lockKey);
        if (Objects.nonNull(cycleId)) {
            RedisUtil.getInstance().delObj(lockKey);
        }
    }

    @Override
    public BigDecimal getTotalAmountWithList(List<Integer> cycleAddIdList) {
        List<ServiceWithdarwCycleAdd> list = baseMapper.getTotalAmountWithList(cycleAddIdList);
        BigDecimal amount = BigDecimal.ZERO;
        for (ServiceWithdarwCycleAdd serviceWithdarwCycleAdd : list) {
            amount = amount.add(serviceWithdarwCycleAdd.getTotal().subtract(serviceWithdarwCycleAdd.getTotal().multiply(serviceWithdarwCycleAdd.getRatio())));
        }

        return amount;
    }


    /**
     * 更新提现打款乐税注销状态
     *
     * @param cycleAdd
     */
    public PayMoneyResult updateWithdrawLogLetaxStatus(String platformCode, String merchantTaxNumber, ServiceWithdarwCycleAddDto cycleAdd) {
        PayMoneyResult payMoneyResult = new PayMoneyResult();

        //请求乐税第三方
        ServiceLetaxRegisteredReturnResult merchantInfo;
        try {
            log.info("[服务费后台][个人收益打款申请记录][周期打款][获取商户信息获取]idCode{},platformCode{}", cycleAdd.getIdCode(), platformCode);
            merchantInfo = serviceLetaxRegisteredService.getMerchantInfo(cycleAdd.getIdCode());
        } catch (Exception e) {
            log.error("[服务费后台][个人收益打款申请记录][周期打款][获取商户信息获取异常,异常信息]:", e);
            //更新交易记录表
            serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), cycleAdd.getNum() + 1, ServiceWithdarwCycleAddTransOrderEnum.FAILURE.getCode(), "乐税查询商户信息：" + e.getMessage());
            //失败释放缓存
            delRedisKey(cycleAdd.getId());
            MsgSendUtil.sendLarkMsg(e.getMessage());
            return payMoneyResultData(Boolean.FALSE, cycleAdd.getAlertTitle() + e.getMessage());
        }

        //税号不一致或者商户是注销状态打标记
        if (!merchantInfo.getMerchantTaxNumber().equals(merchantTaxNumber) || LetaxMerchantCodeEnum.CANCEL.getCode().equals(merchantInfo.getStateCode())) {
            //更新提现记录
            serviceLetaxWithdrawLogServiceImpl.updateLogAndTransOrder(cycleAdd);

            //成功释放缓存
            delRedisKey(cycleAdd.getId());
            return payMoneyResultData(Boolean.FALSE, cycleAdd.getAlertTitle() + "商户状态为注销！");
        }
        payMoneyResult.setPayResult(Boolean.TRUE);
        return payMoneyResult;
    }

    //获取每页参数
    private int getPage(long count) {
        return Math.toIntExact((count / pageSize + (count % pageSize > 0 ? 1 : 0)));
    }

}
